package com.mh.controller;

import com.google.gson.Gson;
import com.mh.pojo.Hotel;
import com.mh.pojo.SearchVo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.unit.DistanceUnit;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Random;


/**
 * Date:2024/8/28
 * author:zmh
 * description:ES控制器
 **/


@RestController
@RequestMapping("/es")
@RequiredArgsConstructor
@Slf4j
@CrossOrigin
public class EsController {

    private final RestHighLevelClient client;
    Gson gson = new Gson();

    @PostMapping
    public String addHandle(@RequestBody Hotel hotel) throws IOException {
        // 设置模拟图片p1-p6.webp
        hotel.setPicture(getRandomPicture());
        // 构建新增请求
        IndexRequest request = new IndexRequest("hotels").id(hotel.getId());
        // 准备数据
        request.source(gson.toJson(hotel), XContentType.JSON);
        IndexResponse index = client.index(request, RequestOptions.DEFAULT);
        log.info(index+"===");
        return "新增成功";
    }

    // 模拟-随机生成 p1.webp 到 p6.webp 的图片名称 （小demo就不做文件上传下载操作了）
    private String getRandomPicture() {
        Random random = new Random();
        int picNumber = random.nextInt(6) + 1; // 生成1到6之间的随机数
        return "p" + picNumber + ".webp"; // 拼接成图片名称
    }

    @PostMapping("/searchByLocation")
    public List<Map<String, Object>> searchHotelsByLocation(
            @RequestBody SearchVo searchVo
            ) throws IOException {

        // 构建查询请求
        SearchRequest searchRequest = new SearchRequest("hotels");

        // 构建查询DSL
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        boolQuery.filter(QueryBuilders.geoDistanceQuery("location")
                .point(searchVo.getLat(), searchVo.getLon())
                .distance(searchVo.getRadiusKm(), DistanceUnit.KILOMETERS));

        sourceBuilder.query(boolQuery);
        sourceBuilder.sort(SortBuilders.geoDistanceSort("location", searchVo.getLat(), searchVo.getLon())
                .order(SortOrder.ASC)
                .unit(DistanceUnit.KILOMETERS));

        searchRequest.source(sourceBuilder);

        // 执行查询
        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
        SearchHits hits = searchResponse.getHits();
        List<Map<String, Object>> hotels = new ArrayList<>();

        for (SearchHit hit : hits) {
            Map<String, Object> hotel = hit.getSourceAsMap();
            // 可以获取距离信息（如果需要显示距离）
            double distance = (double) hit.getSortValues()[0];
            hotel.put("distance_km", distance);
            hotels.add(hotel);
        }

        return hotels;
    }

    @DeleteMapping
    public void test() throws IOException {
        DeleteIndexRequest request = new DeleteIndexRequest("hotels");
        client.indices().delete(request, RequestOptions.DEFAULT);
    }
}
